/*
 * Copyright (c) 2020-2021 Du Tian Wei
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import router from '@system.router';
import fileio from '@ohos.fileio';
import * as obvm from '../../common/runtime/vm.js';
import * as obcanvaslib from '../../common/canvas.js'
import featureAbility from '@ohos.ability.featureAbility'
import prompt from '@system.prompt';
import app from '@system.app';

let filepath = '/data/openblock.xe';
// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
if (!String.prototype.padStart) {
    String.prototype.padStart = function padStart(targetLength,padString) {
        targetLength = targetLength>>0; //floor if number or convert non-number to 0;
        padString = String((typeof padString !== 'undefined' ? padString : ' '));
        if (this.length > targetLength) {
            return String(this);
        }
        else {
            targetLength = targetLength-this.length;
            if (targetLength > padString.length) {
                padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
            }
            return padString.slice(0,targetLength) + String(this);
        }
    };
}
if (!Object.values) Object.values = function(obj) {
    if (obj !== Object(obj))
        throw new TypeError('Object.values called on a non-object');
    var val=[],key;
    for (key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj,key)) {
            val.push(obj[key]);
        }
    }
    return val;
}



export default {
    data: {
        info: "info:",
        vm: null,
        fsm: null,
        uninited: true,
        updateInterval: 0,
        fileCheckInterval: 0,
        filectime: -1,
        ui: [{
                 type: 'button'
             }]
    },
    log(s) {
        console.log('OpenBlock '+s);
        this.info +="\n"+ s;
    },
    ob_event(name) {
        this.log(name);
        try {
            if (this.vm) {
                this.log("1");
                this.vm.BroadcastMessage(new obvm.OBEventMessage(name, "", null, null));
                this.log("2");
            }
        } catch (e) {
            this.log(e + "");
        }
    },
    ob_click(e) {
        this.ob_event("click");
    },
    touchStart(e) {
        this.ob_event("touchstart");
    },
    ob_touchmove(e) {
        this.ob_event("touchmove");
    },
    ob_touchend(e) {
        this.ob_event("touchend");
    },
    ob_longpress(e) {
        this.ob_event("longpress");
    },
    ob_swipe(e) {
        this.ob_event("swipe");
    },
    initStage() {

        var context = featureAbility.getContext();
        context.getOrCreateLocalDir().then((dir) => {
//            this.log("root dir=" + dir);
            let stage = this.$refs.canvas1;

            try {
//                console.log('openblock 中文'+'测试');
                // /storage/media/100/local/files

                filepath = dir + "/main.xe";//"/data/"+app.getInfo().appID+"/main.xe";
//                this.log(filepath);
//                stage.width = stage.width;
                let fd = fileio.openSync(filepath, 0o2);
                let st = fileio.fstatSync(fd);
                let scriptArrayBuffer = new ArrayBuffer(st.size);
                fileio.readSync(fd, scriptArrayBuffer);

                let obcanvas = new obcanvaslib.OBCanvas2D(stage);
                //            let ctx = stage.getContext('2d');
                //            ctx.fillRect(15, 15, 50, 50);

                let nativeLibs = [obcanvas.install.bind(obcanvas)];
                let loader = obvm.OBScriptLoader;
                let loadedScript = loader.loadScript(scriptArrayBuffer, nativeLibs);
                this.vm = new obvm.OBVM(loadedScript,{setTimeout:setTimeout,Output:this.log});
                //                // vm.Output = alert.bind(window);
                //            this.vm.Output = this.log;//prompt.showToast;
                let fsmname = 'Start.Main';
                let fsm = this.vm.CreateFSM(fsmname);
                if (!fsm) {
                    this.log('no fsm');
                    throw Error("No FSM named " + fsmname);
                }
                this.log(fsmname + ' created');
                this.fsm = fsm;
            } catch (e) {
                this.log("\nERROR:"+e.toString()+"\n" + JSON.stringify(e));
            } finally {
            }
        });
    },
    pageError(e){
        this.log(e.message);
    },
    onActive() {
        setTimeout(()=>{
            if (this.uninited) {
                this.uninited = false;
                this.initStage();
            }
            this.updateInterval = setInterval(this.update, 5000);
            this.fileCheckInterval = setInterval(this.checkFile, 3000);
        },1);
    },
    checkFile() {
//        let fd = fileio.openSync(filepath, 0o2);
        let stat = fileio.statSync(filepath);
        let ctime = stat.ctime;
//        fileio.closeSync(fd);
        if (this.filectime == -1) {
            this.filectime = ctime;
        } else if (this.filectime != ctime) {
            this.filectime = ctime;
            this.initStage();
        }
    },
    onInactive() {
        clearInterval(this.updateInterval);
        clearInterval(this.fileCheckInterval);
    },
    update() {
        if(this.info.length > 500){
            this.info = this.info.substring(500);
        }
        try {
            if (this.vm) {
                this.vm.update();
            }
        }catch(e){
            this.log("\nERROR:"+e.toString()+"\n" + JSON.stringify(e));
        }
    },
    onchange(type) {
        router.push({
            uri: "pages/" + type + "/index"
        })
    }
}
